#include "Base.h"
#include "Sub.h"

int Base::N = 0;

int main(void)
{
	// Test Base
	Base base; 
	Base baseA("BaseA"); 
	Base *baseB = new Base(2);			// Pointer to class 
	Base *baseC = new Base("BaseC", 3);
	Base *baseD = new Base[2];			// Arroy of class

	base.print();
	
	baseA.set(1);
    baseA.setToken(5);
    //cout << baseA.getN() << endl; 
	baseA.print();

	baseB->set("BaseB");
    baseB->setToken(8);
	baseB->print();

	
	(*baseC).print();

	baseD[0].set("BaseD0", 4);
	baseD[1].set("BaseD1", 5);
	baseD->print();
	baseD[1].print();
  
    Base baseE = baseA + *baseB;
	//Q: Following code crash if there is no "operator=()", why?
	//Base baseE;
	//baseE = baseA + *baseB;
	friendPrint(baseE);	// use friend function to access private variables
	
	Base baseF = baseA - *baseB;
	//BaseFriend basefriend;
	//basefriend.printOther(baseF);
	cout << baseF << endl;
	//cin >> baseF;
	
    Base baseG = baseA * *baseB;
    friendPrint(baseG);

	delete baseB; 
	delete baseC;
	delete[] baseD;
	
	// Test sub-classes
	Suba subA("SubaA");
	Subb subB;
	subA.print();
	subB.set("SubbA");
	subB.print();
	

	// Polymorphism
	Base *ptr1, *ptr2, ptr5;
  	AbstractBase *ptr3, *ptr4;
	ptr1 = &subA;
	ptr2 = &subB;
  	ptr3 = &subA;
  	ptr4 = &subB;
	ptr1->print();
	ptr2->print();
	ptr1->printSelf();
	ptr2->printSelf();
  	ptr5.printSelf();

	// Q: Why following code is not valid?
	// AbstractBase, absbase;
	AbstractBase *aptr1, *aptr2;
	aptr1 = new Suba("SubaB");
	aptr2 = new Subb("SubbB");
	// Q: Why can not use aptr1->set()?
	// aptr1->set("SubaB");
	// aptr2->set("SubbB");
	aptr1->printSelf();
	aptr2->printSelf();
	// aptr1 cannot be deleted unless Base destructor is virtual
  	//delete aptr1;
  	//delete aptr2;

	return 0;
}
